﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using ApartmentBillsManager.Start.Annotations;
using ApartmentBillsManager.Start.Common;
using ApartmentBillsManager.Start.Manager.Interfaces;
using ApartmentBillsManager.Start.Services;

namespace ApartmentBillsManager.Start.Manager
{
    class ManagerMainWindow : INotifyPropertyChanged
    {
        private readonly WelcomeContent _welcomeContent;
        private readonly ApartmentManager _apartmentManager;
        private IContent _currentContent;

        public ManagerMainWindow()
        {
            _welcomeContent = new WelcomeContent();
            _apartmentManager = new ApartmentManager();

            _welcomeContent.CreateNewApartmentEvent += CreateNewApartment;
            _welcomeContent.LoadExistingApartmentEvent += LoadExistingApartment;

            if (SaveLoadApartment.IsLastLoadedApartmentExists)
            {
                var lastApartmentPath = SaveLoadApartment.LastLoadedApartmentPath;
                LoadExistingApartment(lastApartmentPath);
            }
            else
            {
                CurrentContent = _welcomeContent;
            }
        }

        public IContent CurrentContent
        {
            get { return _currentContent; }
            set
            {
                _currentContent = value;
                OnPropertyChanged("CurrentContent");
            }
        }

        public bool IsApartmentLoaded
        {
            get { return _apartmentManager.LoadedApartment != null; }
        }

        #region Methods
        public void CreateNewApartment(object obj)
        {
            if (_apartmentManager.LoadedApartment != null)
            {
                var answer = MessageBox.Show("Unsaved changes will be lost, do you want to continue?", "Create New Apartment", MessageBoxButton.YesNo);

                if (answer != MessageBoxResult.Yes) return;
            }

            var newApartment = ObjectsFactory.CreateNewApartment();

            if (newApartment != null)
            {
                _apartmentManager.LoadApartment(newApartment);

                CurrentContent = _apartmentManager;

                OnPropertyChanged("IsApartmentLoaded");
            }
        }

        public void EditCurrentApartment(object obj)
        {
            var editedApartment = ObjectsFactory.EditExistingApartment(_apartmentManager.LoadedApartment);

            if (editedApartment != null)
                _apartmentManager.LoadApartment(editedApartment);
        }

        public void SaveApartment(object obj)
        {
            SaveLoadApartment.SaveApartment(_apartmentManager.LoadedApartment);
        }

        public void SaveApartmentAs(object obj)
        {
            SaveLoadApartment.SaveApartmentAs(_apartmentManager.LoadedApartment);
        }

        public void LoadExistingApartment(object obj)
        {
            if (_apartmentManager.LoadedApartment != null)
            {
                var answer = MessageBox.Show("Unsaved changes will be lost, do you want to continue?", "Create New Apartment", MessageBoxButton.YesNo);

                if (answer != MessageBoxResult.Yes) return;
            }

            Apartment apartment;
            if (obj is string)
                apartment = SaveLoadApartment.LoadApartment(obj as string);
            else
                apartment = SaveLoadApartment.LoadApartment();

            if (apartment != null)
            {
                _apartmentManager.LoadApartment(apartment);

                CurrentContent = _apartmentManager;

                OnPropertyChanged("IsApartmentLoaded");
            }
        }

        public void CloseCurrentApartment(object obj)
        {
            var answer = MessageBox.Show("Unsaved changes will be lost, do you want to continue?", "Create New Apartment", MessageBoxButton.YesNo);

            if (answer != MessageBoxResult.Yes) return;

            _apartmentManager.LoadedApartment = null;

            CurrentContent = _welcomeContent;

            SaveLoadApartment.ClearLastLoadedApartmentPath();

            OnPropertyChanged("IsApartmentLoaded");
        }

        private void Exit(object obj)
        {
            var answer = MessageBoxResult.Yes;
            if (_apartmentManager.LoadedApartment != null)
            {
                answer = MessageBox.Show("Unsaved changes will be lost, do you want to continue?", "Exit", MessageBoxButton.YesNo);
            }

            if (answer == MessageBoxResult.Yes)
            {
                Application.Current.MainWindow.Close();
            }
        }
        #endregion

        #region Commands
        public ICommand CreateNewApartmentCommand
        {
            get { return new DelegateCommand(CreateNewApartment); }
        }

        public ICommand EditCurrentApartmentCommand
        {
            get { return new DelegateCommand(EditCurrentApartment); }
        }

        public ICommand SaveApartmentCommand
        {
            get { return new DelegateCommand(SaveApartment); }
        }

        public ICommand SaveApartmentAsCommand
        {
            get { return new DelegateCommand(SaveApartmentAs); }
        }

        public ICommand LoadExistingApartmentCommand
        {
            get { return new DelegateCommand(LoadExistingApartment); }
        }

        public ICommand CloseCurrentApartmentCommand
        {
            get { return new DelegateCommand(CloseCurrentApartment); }
        }

        public ICommand ExitCommand
        {
            get { return new DelegateCommand(Exit); }
        }
        #endregion

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
